package cn.starrysky108.simpleerp.core.util;

import cn.starrysky108.simpleerp.core.enums.FileTypeEnum;
import org.apache.commons.io.FilenameUtils;
import org.apache.tika.Tika;
import org.springframework.util.StringUtils;

import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.time.LocalDate;
import java.util.UUID;

/**
 * @author Carl Lee
 */
public class UploadUtil {
    /**
     * 文件名前缀长度
     */
    public static final int FILE_NAME_PREFIX_LENGTH = 33;

    /**
     * 获取md5
     *
     * @param stream 输入流
     * @return md5
     */
    public static String getMd5(InputStream stream) {
        try {
            MessageDigest digest = MessageDigest.getInstance("MD5");
            byte[] buf = new byte[8192];
            int len;
            while ((len = stream.read(buf)) > 0) {
                digest.update(buf, 0, len);
            }
            return StringUtil.toHexString(digest.digest());
        } catch (IOException | NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return "";
    }

    /**
     * 创建文件所在的文件夹
     *
     * @param path 文件路径
     */
    public static void initDirectory(Path path) throws IOException {
        Path dest = Files.isDirectory(path) ? path : path.getParent();
        if (!Files.exists(dest)) {
            //创建文件夹
            Files.createDirectories(dest);
        }
    }

    /**
     * 根据文件名转化为在服务器中存储的实际文件
     * a/b/c.txt --&gt; 2021/10/02/8e3cb9a4-2fc4-46c1-beef-66a4417a4180-c.txt
     *
     * @param file 文件名，可以带路径
     * @return 实际文件存储的文件
     */
    public static String getDestFile(String file) {
        //获取实际文件名
        String fileName = FilenameUtils.getName(file);
        if (!StringUtils.hasText(fileName)) {
            return "";
        }
        //存储路径为年/月/日/
        String path = LocalDate.now().toString().replace("-", "/") + "/";
        //文件名由36位的UUID+“-”+原始文件名构成
        String newFileName = String.valueOf(UUID.randomUUID()).replace("-", "") + "-" + fileName;
        return path + newFileName;
    }

    /**
     * 根据文件名获取文件类型
     * 注：本方法未对mime为application*的进行具体分类
     *
     * @param file 文件名
     * @return 默认返回OTHERS
     */
    public static FileTypeEnum getFileType(InputStream file) {
        Tika tika = new Tika();
        String type;
        try {
            type = tika.detect(file);
        } catch (IOException e) {
            //出现异常直接返回OTHERS
            return FileTypeEnum.OTHERS;
        }
        if (type.startsWith(FileTypeEnum.IMAGE.getMimePrefix())) {
            return FileTypeEnum.IMAGE;
        } else if (type.startsWith(FileTypeEnum.AUDIO.getMimePrefix())) {
            return FileTypeEnum.AUDIO;
        } else if (type.startsWith(FileTypeEnum.VIDEO.getMimePrefix())) {
            return FileTypeEnum.VIDEO;
        } else if (type.startsWith(FileTypeEnum.DOCUMENT.getMimePrefix())) {
            return FileTypeEnum.DOCUMENT;
        } else {
            //默认格式
            return FileTypeEnum.OTHERS;

        }
    }

    /**
     * 返回实际文件名
     *
     * @param file 数据库文件信息
     * @return 实际文件名
     */
    public static String getFileName(String file) {
        if (StringUtils.hasText(file)) {
            return file.substring(FILE_NAME_PREFIX_LENGTH);
        }
        return "null";
    }

    /**
     * 规范化路径
     * @param path not null
     */
    public static String normalize(String path){
        return FilenameUtils.normalize(path);
    }
}
